/*
 *	LCD interface example
 *	Uses routines from delay.c
 *	This code will interface to a standard LCD controller
 *	like the Hitachi HD44780. It uses it in 4 bit mode, with
 *	the hardware connected as follows (the standard 14 pin 
 *	LCD connector is used):
 *	
 *	PORTB bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
 *	PORTA bit 2 is connected to the LCD RS input (register select)
 *	PORTA bit 3 is connected to the LCD EN bit (enable)
 *	
 *	To use these routines, set up the port I/O (TRISA, TRISB) then
 *	call lcd_init(), then other routines as required.
 *	
 */

//#include	<pic.h>
#include   "lcd.h"

#define L_A

extern unsigned   int8    latb_tmp;

#define D_Y_L delay_us(36)
#define D_Y_H delay_us(1650)
#bit LCD_RS= LATC.0	// Register select
#bit LCD_EN= LATC.5	// Enable
#bit LCD_W= LATC.1		// Enable
//#define	LCD_STROBE	LCD_EN = 1; LCD_EN=0;
#define	LCD_STROBE	{\
                    LCD_EN = 1;\
                    delay_cycles(1);\
                    LCD_EN = 0;\
                    }//((LCD_EN = 1),(LCD_EN = 0));
//const	char	c1=0b01000000;
//external	int8	latb_tmp;	

//define 8 characters i cgram on LCD 0x00 -> 0x07
void
cgram_write(void)						//define user symbols
{
    //char	c1=0b01000000;
    char    s2=0;
    char    s1=0;
    for (s2=0;s2<6;s2++) {
        for (s1=0;s1<8;s1++) {
            LCD_RS=0;
            LCD_W=0; 
            lcd_write(0b01000000+s1+(s2<<3));
            switch(s2) {
                case 0:
                    lcd_putch(0b00000000);
                    break;
                case 1:
                    lcd_putch(0b00010000);
                    break;
                case 2:
                    lcd_putch(0b00011000);
                    break;
                case 3:
                    lcd_putch(0b00011100);
                    break;
                case 4:
                    lcd_putch(0b00011110);
                    break;
                case 5:
                    lcd_putch(0b00011111);
                    break;
            }
        }
    }
    lcd_clear();
}
/* read kb 4 buttons */

unsigned int8 kb_read(void)
{
    unsigned int8 kb,temp_trisb;
    temp_trisb=GET_TRIS_B();
    LCD_EN=0;
    LATB=LATB|0x0F;
    SET_TRIS_B(0x0F|temp_trisb);
    kb=~(PORTB|0xF0);
    SET_TRIS_B(0xF0&temp_trisb);
    return kb;
}

/* write a byte to the LCD in 4 bit mode */

void
lcd_write(unsigned char c)
{
#ifdef L_A
    int8 out_b;
    //LATB = ((LATB & 0xF0) |  (c >> 4));
    out_b=c>>4;
    LATB=out_b|latb_tmp;
    //LATB=out_b|LATB;
    LCD_STROBE;
    //LATB = ((LATB & 0xF0) |  (c & 0x0F));
    out_b=c&0x0f;
    LATB=out_b|latb_tmp;
    //LATB=out_b|LATB;
    LCD_STROBE;
    D_Y_L;
#endif
#ifndef L_A	
    PORTB = (LATB & 0xF0) |  (c >> 4);
    LCD_STROBE;
    PORTB = (LATB & 0xF0) |  (c & 0x0F);
    LCD_STROBE;
    D_Y_L;
#endif
}

/*
 * 	Clear and home the LCD
 */

void
lcd_clear(void)
{
    LCD_RS = 0;
    lcd_write(0x1);
    D_Y_H;
}

/* write a string of chars to the LCD */

void
lcd_puts(char * s)
{
    LCD_RS = 1; // write characters
    while(*s)
        lcd_write(*s++);
}


/* write one character to the LCD */
#ifdef L_A 
void
lcd_putch(unsigned char c)
{
    int8 out_b;
    LCD_RS = 1; // write characters
    //LATB = ((LATB & 0xF0) |  (c >> 4));
    out_b=c>>4;
    LATB=out_b|latb_tmp;
    //LATB=out_b|LATB;
    LCD_STROBE;
    //LATB = ((LATB & 0xF0) |  (c & 0x0F));
    out_b=c&0x0f;
    LATB=out_b|latb_tmp;
    //LATB=out_b|LATB;
    LCD_STROBE;
    D_Y_L;
}
#endif

#ifndef L_A
void
lcd_putch(char c)
{
    LCD_RS = 1; // write characters
    PORTB = ((PORTB & 0xF0) |  (c >> 4));
    LCD_STROBE;
    PORTB = ((PORTB & 0xF0) |  (c & 0x0F));
    LCD_STROBE;
    D_Y_L;
}

#endif

/*
 * Go to the specified position
 */

void
lcd_goto(unsigned char pos)
{
    LCD_RS = 0;
    lcd_write(0x80+pos);//
    D_Y_H;
}

/* initialise the LCD - put into 4 bit mode */

void
lcd_init(void)
{
    LCD_W   =0;
    LCD_RS  = 0;        // write control bytes
    delay_ms(30);       // power on delay
    LATB = ((LATB & 0xF0) |  0x3);  //PORTB =( LATB | 0x3); // attention!
    LCD_STROBE;
    delay_ms(5);
    LCD_STROBE;
    delay_us(100);
    LCD_STROBE;
    delay_ms(5);
    //  PORTB = (LATB -1 ) ;PORTB | 0x2;    // set 4 bit mode
    LATB = ((LATB & 0xF0) |  0x2);      //PORTB=PORTB - 1;
    LCD_STROBE;
    delay_us(40);
    lcd_write(0x28);    // 4 bit mode, 1/16 duty, 5x8 font
    lcd_write(0x08);    // display off
    lcd_write(0x0C);    // display on, blink curson on
    lcd_write(0x06);    // entry mode
    cgram_write();
}
